home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / lib / mntc6846.zoo / patch / sfadd.s < prev    next >
Encoding:
Text File  |  1994-11-26  |  4.7 KB  |  176 lines

  1.  ! C68 4 byte floating point add/subtract routines
  2.  !-----------------------------------------------------------------------------
  3.  !  Based on _dfadd.s
  4.  !
  5.  !  #1  Redid register usage, and then added wrapper routine
  6.  !    to provide C68 IEEE compatibility    Dave & Keith Walker    02/92
  7.  !  #2  Changed exit code to put pointer to result in D0   Dave Walker  12/92
  8.  !  #3  Changed entry/exit code for C68 v4.3 compatibility
  9.  !    Removed ACK entry points.                    09/93
  10.  !-----------------------------------------------------------------------------
  11.  
  12.     .sect .text
  13.  
  14.     .define .Xsfadd
  15.     .define .Xsfsub
  16.     .define .Xassfadd
  17.     .define .Xassfsub
  18.  
  19. SAVEREG    =    4*4        ! size of saved registers ons tack
  20.  
  21. !----------------------------------------
  22. !    sp    Return address
  23. !    sp+4    address of result
  24. !    sp+8    address of v
  25. !    sp+12    address of u
  26. !----------------------------------------
  27. .Xsfadd:
  28.     moveq.l    #0,d0
  29.     bra    1f
  30. .Xsfsub:
  31.     move.l    #0x80000000,d0    ! reverse sign of v
  32. 1:
  33.     movem.l    d2-d4/d6,-(sp)        ! save registers that get corrupted
  34.     move.l    SAVEREG+12(sp),a1    ! address of v
  35.     move.l    (a1),d4            ! load v
  36.     move.l    SAVEREG+8(sp),a1    ! address of u
  37.     move.l    (a1),d6            ! load u
  38.     move.l    SAVEREG+4(sp),a1    ! result address
  39.     bsr    sfaddsub
  40.     movem.l    (sp)+,d2-d4/d6        !  restore saved registers
  41.  
  42.     move.l    (sp)+,a0        ! get return address
  43.     lea    12(sp),sp        ! remove 3 parameters from stack
  44.     jmp    (a0)            ! ... and return
  45.  
  46.  
  47. !----------------------------------------
  48. !    sp    Return address
  49. !    sp+4    address of result/v
  50. !    sp+8    address of u
  51. !----------------------------------------
  52. .Xassfadd:
  53.     moveq.l    #0,d0            ! set for add
  54.     bra    1f
  55.  
  56. .Xassfsub:
  57.     move.l    #0x80000000,d0        ! set for subtract
  58.     
  59. 1:    movem.l    d2-d4/d6,-(sp)        ! save registers that get corrupted
  60.     move.l    SAVEREG+8(sp),a1
  61.     move.l    (a1),d4
  62.     move.l    SAVEREG+4(sp),a1
  63.     move.l    (a1),d6
  64.     bsr    sfaddsub
  65.     movem.l    (sp)+,d2-d4/d6        ! restore saved registers
  66.  
  67.     move.l    (sp)+,a0        ! get return address
  68.     move.l    (sp),d0            ! address of v returned as result
  69.     addq.l    #8,sp            ! remove 2 parameters from stack
  70.     jmp    (a0)            ! ... and return
  71.  
  72.  !-------------------------------------------------------------------------
  73.  ! This is the routine that actually carries out the operation.
  74.  !
  75.  ! Register usage:
  76.  !
  77.  !        Entry                Exit
  78.  !
  79.  !    d0    add/subtract mask        undefined
  80.  !    d1    ?                undefined
  81.  !    d2    ?                undefined
  82.  !    d3    ?                undefined
  83.  !    d4    v                undefined
  84.  !    d6    u                undefined
  85.  !    A1    Address for result        preserved
  86.  !
  87.  !-----------------------------------------------------------------------------
  88.  
  89. sfaddsub:
  90.     eor.l    d0,d4        ! reverse sign of v if needed (frees d0 for use)
  91.     move.l    d6,d0        ! d0 = u.exp
  92.     swap    d0
  93.     move.l    d6,d2        ! d2.h = u.sign
  94.     move.w    d0,d2
  95.     lsr.w    #7,d0        ! get exponent in least significant bits
  96.     and.w    #0x0ff,d0    ! kill sign bit
  97.  
  98.     move.l    d4,d1        ! d1 = v.exp
  99.     swap    d1
  100.     eor.w    d1,d2        ! d2.l = u.sign ^ v.sign
  101.     lsr.w    #7,d1
  102.     and.w    #0x0ff,d1    ! kill sign bit
  103.  
  104.     and.l    #0x07fffff,d6    ! remove exponent from u.mantissa
  105.     tst.w    d0        ! check for zero exponent - no leading "1"
  106.     beq    0f
  107.     or.l    #0x800000,d6    ! restore implied leading "1"
  108.     bra    1f
  109. 0:    add.w    #1,d0        ! "normalize" exponent
  110. 1:
  111.     and.l    #0x07fffff,d4    ! remove exponent from v.mantissa
  112.     tst.w    d1        ! check for zero exponent - no leading "1"
  113.     beq    0f
  114.     or.l    #0x800000,d4    ! restore implied leading "1"
  115.     bra    1f
  116. 0:    add.w    #1,d1        ! "normalize" exponent
  117. 1:
  118.     clr.w    d3        ! (put initial zero rounding bits in d3)
  119.     neg.w    d1        ! d1 = u.exp - v.exp
  120.     add.w    d0,d1
  121.     beq    5f        ! exponents are equal - no shifting neccessary
  122.     bgt    1f        ! not equal but no exchange neccessary
  123.     exg    d4,d6        ! exchange u and v
  124.     sub.w    d1,d0        ! d0 = u.exp - (u.exp - v.exp) = v.exp
  125.     neg.w    d1
  126.     tst.w    d2        ! d2.h = u.sign ^ (u.sign ^ v.sign) = v.sign
  127.     bpl    1f
  128.     bchg    #31,d2
  129. 1:
  130.     cmp.w    #24,d1        ! is u so much bigger that v is not
  131.     bge    7f        ! significant ?
  132.  
  133.     move.w    #7-1,d3        ! shift u left up to 7 bits to minimize loss
  134. 2:
  135.     add.l    d6,d6
  136.     sub.w    #1,d0        ! decrement exponent
  137.     sub.w    #1,d1        ! done shifting altogether ?
  138.     dbeq    d3,2b        ! loop if still can shift u.mant more
  139.     clr.w    d3
  140. 3:
  141.     cmp.w    #16,d1        ! see if fast rotate possible
  142.     blt    4f
  143.     or.b    d2,d3
  144.     sne    d2        ! "sticky byte"
  145.     clr.w    d4
  146.     swap    d4
  147.     sub.w    #16,d1
  148.     bra    3b
  149. 0:
  150.     lsr.l    #1,d4        ! shift v.mant right the rest of the way
  151.     or.b    d3,d2        ! set "sticky byte" if necessary
  152.     roxr.w    #1,d3        ! shift into rounding bits
  153. 4:    dbra    d1,0b        ! loop
  154.     and.b    #1,d2        ! see if "sticky bit" should be set
  155.     or.b    d2,d3
  156. 5:
  157.     tst.w    d2        ! are the signs equal ?
  158.     bpl    6f        ! yes, no negate necessary
  159.  
  160.     neg.b    d3        ! negate rounding bits and v.mant
  161.     neg.l    d4
  162. 6:
  163.     add.l    d4,d6
  164.     bcs    7f        ! need not negate
  165.     tst.w    d2        ! opposite signs ?
  166.     bpl    7f        ! do not need to negate result
  167.  
  168.     neg.b    d3        ! negate rounding bits and u.mant
  169.     neg.l    d6
  170.     not.l    d2        ! switch sign
  171. 7:
  172.     move.l    d6,(a1)        ! move result on stack
  173.     move.b    d3,d1        ! put rounding bits in d1 for .norm4
  174.     swap    d2        ! put sign into d2
  175.     jmp    .Xnorm4        ! exit via normalise routine
  176.